package com.danbay.cloud.deviceaccess.service;

import com.danbay.cloud.base.constants.Const;
import com.danbay.cloud.deviceaccess.api.dto.DeviceReg;
import com.danbay.framework.kafka.KafkaContext;
import com.danbay.framework.redis.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.Set;

/**
 * @author SJG
 *         2017/10/20
 *         设备信息缓存
 */
@Service
public class DeviceCacheService {

    private static final String CACHE_MESSAGE_ID = "message_id_key_";

    private static final String DEVICE_REGISTER_KEY = "device_register_key_";

    private final RedisClient redisClient;

    @Autowired
    public DeviceCacheService(RedisClient redisClient) {
        this.redisClient = redisClient;
    }

    /**
     * 设备的hash key
     *
     * @param dev_id 设备id
     * @return
     */
    public String getDevHashKey(String dev_id) {
        Objects.requireNonNull(dev_id);
        return "device:" + dev_id;
    }

    /**
     * 设备注册时获取注册key
     *
     * @param mac mac
     * @return string
     */
    public String getDevRegKey(String mac) {
        return "dev_reg:" + mac;
    }

    /**
     * 设备是否已注册返回devId
     *
     * @param mac mac
     * @return devId
     */
    public String getRegisteredDevId(String mac) {
        String regKey = getDevRegKey(mac);
        return redisClient.get(regKey);
    }

    /**
     * 设备是否已注册
     *
     * @param mac mac
     * @return boolean
     */
    public boolean isRegistered(String mac) {
        String regKey = getDevRegKey(mac);
        return redisClient.hasKey(regKey);
    }

    /**
     * 设备是否已注册
     *
     * @param devId 设备id
     * @return boolean
     */
    public boolean devIdIsRegistered(String devId) {
        String devHashKey = getDevHashKey(devId);
        return redisClient.hasKey(devHashKey);
    }

    /**
     * 得到设备的在线状态
     *
     * @param deviceID 设备ID
     * @return true表示在线，false表示离线
     */
    public boolean isDeviceOnline(String deviceID) {
        return redisClient.hasKey(getDeviceOnlineKey(deviceID));
    }

    private String getDeviceOnlineKey(String deviceID) {
        return Const.DEVICE_ONLINE_KEY + deviceID;
    }


    /**
     * 获取设备关联中控设备id
     *
     * @param devId 设备id
     * @return 中控设备id
     */
    public String getDeviceCtrlId(String devId) {
        String devHashKey = getDevHashKey(devId);
        if (!redisClient.hasKey(devHashKey)) {
            return null;
        }
        return redisClient.hget(devHashKey,"ctrlDevId").toString();
    }

    public void setMsgId(String pwdKey, String messageId) {
        redisClient.set(CACHE_MESSAGE_ID + pwdKey, messageId);
    }

    public void setRegMsg(String deviceId, DeviceReg deviceReg) {
        redisClient.setEntity(DEVICE_REGISTER_KEY + deviceId, deviceReg);
    }

    public DeviceReg getDeviceReg(String deviceId) {
        return redisClient.getEntity(DEVICE_REGISTER_KEY + deviceId);
    }

    /**
     * 缓存设备topic
     *
     * @param devId 设备id
     * @param topic 主题
     */
    public void cacheDeviceTopic(String devId, String topic) {
        redisClient.set("device_topic:" + devId, topic);
        //同一主题设备列表
        String topicDevKey = "device_topic_" + topic;
        String devices = "";
        if (redisClient.hasKey(topicDevKey)) {
            devices = redisClient.get(topicDevKey);
        }
        //添加新的设备到topic列表
        if (!devices.contains(devId)) {
            devices += devId + ",";
            redisClient.set(topicDevKey, devices);
        }
    }

    /**
     * 恢复设备-主题之间的映射关系
     */
    public void recoverDeviceTopicMapping() {
        Set<String> topics = redisClient.keys("device_topic_*");
        for (String topic : topics) {
            String devices = redisClient.get(topic);
            for (String devId : devices.split(",")) {
                KafkaContext.mapTopic(devId, topic);
            }
        }
    }
}
